package com.powernode.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.constant.MenuConstant;
import com.powernode.domain.SysMenu;
import com.powernode.mapper.SysMenuMapper;
import com.powernode.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@Service
@CacheConfig(cacheNames = "com.powernode.service.impl.SysMenuServiceImpl")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService{
    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public List<SysMenu> selectUserMenuList(String userId) {
        // 1. 先从redis缓存中获取用户的菜单集合
        String menuJsonStr = stringRedisTemplate.opsForValue().get(MenuConstant.MENU_PREFIX + userId);
        List<SysMenu> sysMenus = null;

        // 2. 判断是否有值
        if (StrUtil.isNotBlank(menuJsonStr)) {
            // 3. 有则直接返回

            // 3.1 将json格式字符串转换为集合
            JSONArray jsonArray = JSONUtil.parseArray(menuJsonStr);
            sysMenus = JSONUtil.toList(jsonArray, SysMenu.class);


        } else {
            // 4. 没有则查询数据库
            sysMenus = sysMenuMapper.selectUserMenuList(userId);

            // 4.1 将菜单集合转换未json字符串放在redis缓存中
            stringRedisTemplate.opsForValue().set(MenuConstant.MENU_PREFIX + userId, JSONUtil.toJsonStr(sysMenus));
        }

        // 5. 将菜单集合转换为树状结构

        // 如果两级则按照已知去处理
        

        return transformTree(sysMenus, 0L);
    }


    /**
     * 集合转树结构，已知深度和未知深度
     * @param sysMenus
     * @param pid
     * @return
     */
    private List<SysMenu> transformTree(List<SysMenu> sysMenus, long pid) {

        ///////////////////// 已知深度的情况 ////////////////////////
//        // 1. 获取根节点
//        List<SysMenu> roots = sysMenus.stream().filter(item -> item.getParentId().equals(pid)).collect(Collectors.toList());
//
//        // 2. 循环根节点的集合
//        roots.forEach(r -> {
//
//            // 2.1 子节点
//            List<SysMenu> next = sysMenus.stream()
//                    .filter(item -> item.getParentId().equals(r.getMenuId()))
//                    .collect(Collectors.toList());
//
//            // 2.2 将子目录存放在当前的根目录中
//            r.setNextList(next);
//
//        });
//
//        return roots;
        ///////////////////// 已知深度的情况 ////////////////////////

        ///////////////////// 未知深度的情况 ////////////////////////
        // 1. 迭代的基线条件就是没有子孩子
        List<SysMenu> lists = sysMenus.stream().filter(item -> item.getParentId().equals(pid)).collect(Collectors.toList());
        if (lists.size() <= 0) return Collections.emptyList();

        // 2. 如果孩子不为空则遍历设置孩子的列表
        lists.forEach(item -> {
            item.setList(transformTree(sysMenus, item.getMenuId()));
        });

        // 3. 返回孩子
        return lists;
        ///////////////////// 未知深度的情况 ////////////////////////
    }

    @Override
    @Cacheable(key = MenuConstant.ALL_MENU_LIST)
    public List<SysMenu> list() {
        List<SysMenu> menuList = sysMenuMapper.selectList(null);
        return menuList;
    }
}
